#include "TcpConnection.hpp"

#include "SocketIO.hpp"
#include "InetAddress.hpp"
#include "Socket.hpp"

#include <sstream>
#include <iostream>

namespace xww
{
    TcpConnection::TcpConnection(int fd)
    :_sock(fd)
    ,_socketIO(fd)
    ,_localAddr(getlocalAddr()) // 获取本地地址
    ,_peerAddr(getpeerAddr()) // 获取对端地址
    {

    }

    TcpConnection::~TcpConnection()
    {
        shutdown(); // 关闭连接
    }

    string TcpConnection::receive()
    {
        char buf[65535];
        int ret = _socketIO.readn(buf,sizeof(buf));
        if(ret < 0)
        {
            // perror("TcpConnection::receive error");
            return "TcpConnection::receive error";
        }
        return string(buf,ret);// 返回接收到的数据
    }

    void TcpConnection::send(const string &msg)
    {
        //加一个判断，当数据不为空时发送数据
        if(!msg.empty())
        {
            int ret = _socketIO.sendn(msg.c_str(), msg.size());
        }
    }

    //怎么判断连接是否关闭？
    //通过读取数据来判断，如果读取到的数据长度为0，表示连接已关闭
    bool TcpConnection::isClosed() const
    {
        char buf[100];
        int ret = _socketIO.recvPeek(buf, sizeof(buf));
        if(ret == 0)
        {
            return true;
        }  
        return false;
    }

    void TcpConnection::shutdown()
    {
        _sock.shutdownWrite(); // 关闭写端
    }

    //获取连接的字符串表示
    string TcpConnection::toString() const
    {
        std::ostringstream oss;
        oss << "TcpConnection: " << _localAddr.getIp() << ":" << _localAddr.getPort()
            << " ---> " << _peerAddr.getIp() << ":" << _peerAddr.getPort();
        return oss.str();
    }

    //为什么这样写？
    //因为TcpConnection类继承了std::enable_shared_from_this<TcpConnection>的功能
    //从而可以在TcpConnection类的成员函数中使用shared_from_this()函数
    //shared_from_this()函数返回一个指向当前对象的shared_ptr
    //这样可以确保在回调函数中使用TcpConnection对象时，它不会被提前销毁
    //从而避免悬空指针的问题
    void TcpConnection::handleConnectionCallback()
    {
        if(_TonConnection)
        {
            _TonConnection(shared_from_this());
        }
    }

    void TcpConnection::handleMessageCallback()
    {
        if(_TonMessage)
        {
            _TonMessage(shared_from_this());
        }
    }

    void TcpConnection::handleCloseCallback()
    {
        if(_TonClose)
        {
            _TonClose(shared_from_this());
        }
    }

    InetAddress TcpConnection::getlocalAddr()
    {
        struct sockaddr_in addr;// 用于存储本地地址
        socklen_t len = sizeof(addr);// 地址长度
        // 获取本地地址
        // 把本地地址信息填充到addr中
        getsockname(_sock.getfd(), (struct sockaddr*)&addr, &len);
        return InetAddress(addr);// 返回本地地址对象
    }

    InetAddress TcpConnection::getpeerAddr()
    {
        struct sockaddr_in addr;
        socklen_t len = sizeof(addr);
        // 获取对端地址
        // 把对端地址信息填充到addr中
        getpeername(_sock.getfd(), (struct sockaddr*)&addr, &len);
        return InetAddress(addr); // 返回对端地址对象
    }

}// end of namespace xww
